package yunjiao.designpatterns.combinator;

import lombok.extern.slf4j.Slf4j;

import java.util.List;

import static yunjiao.designpatterns.combinator.UsageCombinators.expression;
import static yunjiao.designpatterns.combinator.UsageCombinators.integer;

/**
 * 入口
 *
 * @author yangyunjiao
 */
@Slf4j
public class App {
    public static void main(String[] args) {
        // 测试基础解析器
        Parser<String> helloParser = BasicParsers.string("Hello");
        ParseResult<String> result1 = helloParser.parse("Hello World");
        System.out.println("Parse 'Hello': " + result1.success + ", remaining: " + result1.remaining);

        // 测试整数解析
        Parser<Integer> intParser = integer();
        ParseResult<Integer> result2 = intParser.parse("123 + 456");
        System.out.println("Parse integer: " + result2.value + ", remaining: " + result2.remaining);

        // 测试表达式解析
        Parser<Expr> exprParser = expression();
        String[] testExpressions = {
                "2 + 3",
                "10 - 5 + 3",
                "2 * 3 + 4",
                "(2 + 3) * 4",
                "10 / 2 * 5"
        };

        for (String expr : testExpressions) {
            ParseResult<Expr> result = exprParser.parse(expr);
            if (result.success) {
                System.out.println(expr + " = " + result.value.evaluate() + " [AST: " + result.value + "]");
            } else {
                System.out.println("Failed to parse: " + expr + " - " + result.error);
            }
        }

        // 测试 CSV 解析
        Parser<List<String>> csvParser = Combinators.sepBy(
                Combinators.many1(BasicParsers.letter()).map(chars -> {
                    StringBuilder sb = new StringBuilder();
                    for (Character c : chars) sb.append(c);
                    return sb.toString();
                }),
                BasicParsers.character(',')
        );

        ParseResult<List<String>> csvResult = csvParser.parse("apple,banana,cherry");
        if (csvResult.success) {
            System.out.println("CSV parsed: " + csvResult.value);
        }
    }
}
